/**
 * 外部中断实验
 * PE4 ----> KEY0
 * PE3 ----> KEY1
 * PE5 ----> LED1
 */
#include "pin_map_elite.h"
#include "stm32f10x.h"

u8 key_val = 1;

void RCC_Configuration(void);
void GPIO_Configuration(void);
void EXTI_Configuration(void);
void NVIC_Configuration(void);
void delay_ms(u16 xms);

int main() {
    RCC_Configuration();
    GPIO_Configuration();
    EXTI_Configuration();
    NVIC_Configuration();

    while (1) {
        if (key_val) {
            GPIO_ResetBits(GPIOE, LED1_Pin);
        } else {
            GPIO_SetBits(GPIOE, LED1_Pin);
        }
    }
}

void RCC_Configuration() {
    SystemInit();

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
}

void GPIO_Configuration(void)  //配置GPIO口
{
    GPIO_InitTypeDef GPIO_InitStructure;  //声明GPIO初始化结构变量。

    // LED
    GPIO_InitStructure.GPIO_Pin = LED1_Pin;           //配置管脚5
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  // IO口配置为推挽输出口
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOE, &GPIO_InitStructure);  //初始化PE5口

    // KEY0
    GPIO_InitStructure.GPIO_Pin = KEY0_Pin;        //配置管脚4
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  // IO口配置为上拉输入
    GPIO_Init(GPIOE, &GPIO_InitStructure);         //初始化PE4口

    // KEY1
    GPIO_InitStructure.GPIO_Pin = KEY1_Pin;        //配置管脚3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  // IO口配置为上拉输入
    GPIO_Init(GPIOE, &GPIO_InitStructure);         //初始化PE3口

    GPIO_SetBits(GPIOE, LED1_Pin);  // LED0灭
}

void EXTI_Configuration() {
    EXTI_InitTypeDef EXTI_InitStructure;

    EXTI_InitStructure.EXTI_Line = KEY0_EXTI_LINE | KEY1_EXTI_LINE;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, KEY0_PinSource);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, KEY1_PinSource);


    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource5);
}

void NVIC_Configuration() {
    NVIC_InitTypeDef NVIC_InitStructure;

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);
}

void EXTI3_IRQHandler(void) {
    if (EXTI_GetFlagStatus(EXTI_Line3) != RESET) {
        delay_ms(200);
        key_val = !key_val;
        EXTI_ClearFlag(EXTI_Line3);
    }
}

void EXTI4_IRQHandler(void) {
    if (EXTI_GetFlagStatus(EXTI_Line4) != RESET) {
        EXTI_ClearFlag(EXTI_Line4);
    }
}

void delay_ms(u16 xms) {
    u16 i, j;

    for (i = 0; i < xms; i++) {
        for (j = 0; j < 7992; j++)
            ;
    }
}
